package lastRites.game;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Vector;

import lastRites.entities.Player;
import lastRites.enums.AnimationName;
import lastRites.enums.BlockType;
import lastRites.enums.CreatureType;
import lastRites.enums.GameStatus;
import lastRites.enums.TileSetName;
import lastRites.game.networking.NetworkPackets.TextDisplayPacket;
import lastRites.game.terrain.World;
import lastRites.ui.Item;
import lastRites.ui.ItemStack;

import org.newdawn.slick.Animation;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.StateBasedGame;

import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Server;

public class LastRites extends StateBasedGame {
	public static int														SCREEN_WIDTH		= 640, SCREEN_HEIGHT = 480, TARGET_FRAMERATE = 40;
	public static HashMap<TileSetName, HashMap<BlockType, Image>>			TILE_MAP			= new HashMap<>();
	public static HashMap<String, Image>									MENU_IMAGES			= new HashMap<>();
	public static HashMap<String, Image>									MISC_IMAGES			= new HashMap<>();
	public static HashMap<CreatureType, HashMap<AnimationName, Animation>>	ANIMATION_DIRECTORY	= new HashMap<>();
	public static Vector<Player>											PLAYER_LIST			= new Vector<>();
	public static HashMap<String, Player>									PLAYER_INFO			= new HashMap<>();
	public static LinkedList<String>										CHAT_MESSAGES		= new LinkedList<>();
	public static Vector<TextDisplayPacket>									TEXT_ON_SCREEN		= new Vector<>();
	public static ItemStack													MOUSE_ITEM			= null;
	public static World														CURRENT_WORLD		= null;
	public static Player													THIS_PLAYER			= new Player();
	public static GameStatus												GAME_STATUS			= GameStatus.INITIALNETWORK;
	public static Server													SERVER;
	public static Client													CLIENT;
	public static Vector2f													FRICTION			= new Vector2f();
	public static Vector2f													GRAVITY				= new Vector2f();
	public static int														BLOCK_SIZE			= 16;

	public LastRites(String name) throws SlickException {
		super( name );
	}

	// Start game
	public static void main(String[] args) {
		try {
			System.setProperty( "org.lwjgl.librarypath", new File( System.getProperty( "user.dir" ), "natives" ).getAbsolutePath() );
			System.setProperty( "net.java.games.input.librarypath", System.getProperty( "org.lwjgl.librarypath" ) );
			AppGameContainer app = new AppGameContainer( new LastRites( "Last Rites" ) );
			app.setDisplayMode( SCREEN_WIDTH, SCREEN_HEIGHT, false );
			app.setTargetFrameRate( TARGET_FRAMERATE );
			app.setUpdateOnlyWhenVisible( false );
			app.setAlwaysRender( true );
			app.start();
		} catch( SlickException e ) {
			e.printStackTrace();
		}
	}

	@Override
	public void initStatesList(GameContainer container) throws SlickException {
		LastRitesMainMenu mainMenu = new LastRitesMainMenu();
		LastRitesTerrainDemo terrainTest = new LastRitesTerrainDemo();
		LastRitesNetworkDemo networkTest = new LastRitesNetworkDemo();

		addState( mainMenu );
		addState( terrainTest );
		addState( networkTest );

		// Load Items first!!!!
		loadItems();
		loadTiles();
		loadCharacterAnimations();
		loadMiscImages();

		enterState( networkTest.getID() );
	}

	private void loadTiles() throws SlickException {
		HashMap<BlockType, Image> mountainTiles = new HashMap<>();
		HashMap<BlockType, Image> terrariaBlocks = new HashMap<>();
		// Load terrain pieces
		terrariaBlocks.put( BlockType.DIRT, new Image( "main/rsc/terrain/terraria/dirt_nesw_16x16.png" ) );

		// Build terrain map
		LastRites.TILE_MAP.put( TileSetName.Mountain, mountainTiles );
		LastRites.TILE_MAP.put( TileSetName.Terraria, terrariaBlocks );
	}

	private void loadCharacterAnimations() throws SlickException {
		// Setup Golem's Animations
		HashMap<AnimationName, Animation> golemAnimations = new HashMap<>();
		golemAnimations.put( AnimationName.MOVE_EAST, new Animation( new SpriteSheet( "main/rsc/models/golem/golem_walking_east_32x48.png", 32, 48 ), 250 ) );
		golemAnimations.put( AnimationName.MOVE_WEST, new Animation( new SpriteSheet( new Image( "main/rsc/models/golem/golem_walking_east_32x48.png" ).getFlippedCopy( true, false ), 32, 48 ), 250 ) );
		golemAnimations.put( AnimationName.IDLE_EAST, new Animation( new SpriteSheet( "main/rsc/models/golem/golem_idle_east_32x48.png", 32, 48 ), 100 ) );
		golemAnimations.put( AnimationName.IDLE_WEST, new Animation( new SpriteSheet( new Image( "main/rsc/models/golem/golem_idle_east_32x48.png" ).getFlippedCopy( true, false ), 32, 48 ), 100 ) );
		golemAnimations.put( AnimationName.ATTACK_EAST, new Animation( new SpriteSheet( "main/rsc/models/golem/golem_walking_east_32x48.png", 32, 48 ), 250 ) );
		golemAnimations.put( AnimationName.ATTACK_WEST, new Animation( new SpriteSheet( new Image( "main/rsc/models/golem/golem_walking_east_32x48.png" ).getFlippedCopy( true, false ), 32, 48 ), 250 ) );
		ANIMATION_DIRECTORY.put( CreatureType.GOLEM, golemAnimations );
	}

	private void loadItems() throws SlickException {
		// Images
		MENU_IMAGES.put( "Dirt", new Image( "src/main/rsc/icons/rocks_1_16x16.png" ) );
		// Templates
		Item.DIRT = new Item( "Dirt", LastRites.MENU_IMAGES.get( "Dirt" ), new Animation( new SpriteSheet( "main/rsc/terrain/terraria/dirt_nesw_16x16.png", 16, 16 ), 10000 ), 1, 16, true );
	}

	private void loadMiscImages() throws SlickException {
		MISC_IMAGES.put( "sky", new Image( "main/rsc/terrain/terraria/clouds_and_sky_500x352.png" ) );
		MISC_IMAGES.put( "mountain_range", new Image( "main/rsc/terrain/terraria/mountain_range_500x352.png" ) );
	}
}
